package com.lmf.mock.starter.autoconfigure.controller;

import com.lmf.mock.starter.autoconfigure.entity.ProxyConfig;
import com.lmf.mock.starter.autoconfigure.service.ProxyConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Enumeration;
import java.util.List;

/**
 * 代理转发控制器
 */
@Controller
@Slf4j
public class ProxyController {

    @Autowired
    private ProxyConfigService proxyConfigService;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 代理转发处理
     */
    @RequestMapping(value = "${proxy.base-path:/proxyI}/**")
    public void proxyRequest(HttpServletRequest request, HttpServletResponse response) {
        try {
            // 获取请求路径和方法
            String requestURI = request.getRequestURI();
            String method = request.getMethod();

            // 移除代理前缀
            String contextPath = request.getContextPath();
            String path = removeProxyPrefix(contextPath, requestURI);

            log.info("代理请求: {} {}, 原始路径: {}", method, path, requestURI);

            // 查找匹配的代理配置
            ProxyConfig config = proxyConfigService.getConfigByPathAndMethod(path, method);
            if (config == null) {
                log.warn("未找到匹配的代理配置: {} {}", method, path);
                response.setStatus(HttpStatus.NOT_FOUND.value());
                response.getWriter().write("未找到匹配的代理配置");
                return;
            }

            // 构建目标URL
            String targetUrl = config.getTargetUrl();
//            if (!targetUrl.endsWith("/") && !path.equals("/")) {
//                targetUrl += path;
//            }

            log.info("转发到目标: {}", targetUrl);

            // 转发请求
            forwardRequest(request, response, targetUrl, config);

        } catch (Exception e) {
            log.error("代理转发失败", e);
            try {
                response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
                response.getWriter().write("代理转发失败: " + e.getMessage());
            } catch (IOException ex) {
                log.error("写入错误响应失败", ex);
            }
        }
    }

    /**
     * 移除代理前缀
     */
    private String removeProxyPrefix(String contextPath, String requestURI) {
        String path = contextPath + "/proxyI";
        // 移除 /proxy 前缀
        if (requestURI.startsWith(path)) {
            return requestURI.substring(path.length());
        }
        return requestURI;
    }

    /**
     * 转发请求
     */
    private void forwardRequest(HttpServletRequest request, HttpServletResponse response,
                                String targetUrl, ProxyConfig config) throws IOException, URISyntaxException {

        // 创建HTTP请求头
        HttpHeaders headers = new HttpHeaders();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            String headerValue = request.getHeader(headerName);
            // 跳过一些不应该转发的头部
            if (!"host".equalsIgnoreCase(headerName) &&
                    !"content-length".equalsIgnoreCase(headerName)) {
                headers.set(headerName, headerValue);
            }
        }

        // 读取请求体
        byte[] body = null;
        if (request.getContentLength() > 0) {
            body = IOUtils.toByteArray(request.getInputStream());
        }

        // 创建HTTP实体
        HttpEntity<byte[]> httpEntity = new HttpEntity<>(body, headers);

        // 设置超时
        int timeout = config.getTimeout() != null ? config.getTimeout() : 5000;

        try {
            // 发送请求
            ResponseEntity<byte[]> responseEntity = restTemplate.exchange(
                    new URI(targetUrl),
                    HttpMethod.valueOf(request.getMethod()),
                    httpEntity,
                    byte[].class
            );

            // 设置响应状态
            response.setStatus(responseEntity.getStatusCodeValue());

            // 设置响应头
            responseEntity.getHeaders().forEach((key, values) -> {
                if (!"content-length".equalsIgnoreCase(key)) {
                    values.forEach(value -> response.setHeader(key, value));
                }
            });

            // 写入响应体
            if (responseEntity.getBody() != null) {
                response.getOutputStream().write(responseEntity.getBody());
            }

        } catch (Exception e) {
            log.error("转发请求失败: {}", targetUrl, e);
            response.setStatus(HttpStatus.BAD_GATEWAY.value());
            response.getWriter().write("转发请求失败: " + e.getMessage());
        }
    }
}
